﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using OpenSSL.X509;
using Sicurezza.CA.Manager;
using System.Security.Cryptography.Pkcs;
using Sicurezza.Entita;
using System.Collections.Generic;
using Sicurezza.Manager;


namespace Sicurezza.CA.Server
{
    /// <summary>
    /// Descrizione di riepilogo per CAService
    /// </summary>
    [WebService(Namespace = "http://www.sicurezza.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    // Per consentire la chiamata di questo servizio Web dallo script utilizzando ASP.NET AJAX, rimuovere il commento dalla riga seguente. 
    // [System.Web.Script.Services.ScriptService]
    public class CAService : System.Web.Services.WebService
    {

        

        [WebMethod]
        public SignedMessage SendRequest(string request)
        {

            string ReqId = RequestManager.Save(request);
            //-- Torno il ticket col quale il client richiederà il certificato una
            //-- volta pronto
            return SSLManager.SignMessage(ReqId); 
        }

        [WebMethod]
        public SignedMessage GetCertificate(string ReqId)
        {

            string certificate = null;
            //-- Ritorna nullo se il certificato non è ancora pronto
            //-- altrimenti torna il certificato in formato PEM se la richiesta 
            //-- è andata a buon fine, oppure la ragione del rifiuto se la richiesta
            //-- è stata rifiutata.

            if (ReqId.Contains("req"))
            {
                certificate = RequestManager.Check(ReqId);
            }
            
            if(ReqId.Contains("ren"))
            {
                certificate = RenewManager.Check(ReqId);
            }

            if (!ReqId.Contains("req") && !ReqId.Contains("ren"))
            {
                certificate = X509Manager.Get(ReqId);
            }

            if (certificate == null)
            {
                certificate = SSLManager.GetCertificate(ReqId);
            }

            return SSLManager.SignMessage(certificate);
        }

        [WebMethod]
        public SignedMessage RequestRenew(string serial, string newkey, byte[] sign)
        {
            //-- Safety code
            if (SSLManager.CheckSign(serial+newkey, int.Parse(serial), sign))
            {
                string ReqId = RenewManager.SaveRequest(serial,newkey);
                //-- Torno il ticket col quale il client richiederà il certificato una
                //-- volta pronto
                return SSLManager.SignMessage(ReqId);
            }
            else
                return null;
        }

        [WebMethod]
        public SignedMessage RequestRevoke(string id, byte[] sign)
        { 
            //-- Safety code
            if (SSLManager.CheckSign(id, int.Parse(id), sign))
            {
                RevokeManager.ProcessRequest(id);
            }
            //-- Il valore 1 identifica operazione andata a buon fine
            return SSLManager.SignMessage(Convert.ToString(true));
        }

        [WebMethod]
        public SignedMessage OCSPRequest(int serial)
        {
            OCSPResult state = OCSPResult.Unknow;
            List<RevokedCertificate> revoked = RevokeManager.GetAll();
            RevokedCertificate trovato = revoked.FirstOrDefault(c => c.CertificateSerial==serial);
            if (trovato != null)
                state = OCSPResult.Revoked;
            else
            {
                string cert = X509Manager.Get(serial.ToString());
                if (!string.IsNullOrEmpty(cert))
                    state = OCSPResult.Valid;
            }

            //return SSLManager.SignMessage(Enum.GetName(Type.GetType("OCSPResult"), state));
            return SSLManager.SignMessage(state.ToString());
        }

        [WebMethod]
        public SignedMessage GetRecipients(string serial, string signature, string encipher, byte[] sign)
        {
            //-- Safety code
            if (SSLManager.CheckSign(serial + signature + encipher, int.Parse(serial), sign))
            {
                List<Pair> list = SSLManager.GetAll(Convert.ToBoolean(signature), Convert.ToBoolean(encipher));
                string xmlMessage = XmlManager.Serialize(list);

                return SSLManager.SignMessage(xmlMessage);
            }
            return null;

            }
    }
}
